package org.itsky.hystrix.service;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheResult;
import com.netflix.hystrix.contrib.javanica.command.AsyncResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.Future;

/**
 * @Author sky
 * @Site cmtianxie163.com 2020/4/7 10:14
 */
@Service
public class HelloService {
    @Autowired
    RestTemplate restTemplate;

    /**
     * 这个service方法中 发起一个远程调用 去调用provider中提供的hello接口
     *
     * 但是 这个调用可能会失败
     *
     * 在这个方法上添加 @HystrixCommand 注解，配置fallbackMethod属性，这个属性表示该方法
     * 调用失败时的临时替代方法
     *
     */

    //如果抛异常 不希望服务降级 希望直接抛出异常
    //那么只需要配置 忽略某个异常即可

    @HystrixCommand(fallbackMethod = "tempHello", ignoreExceptions = ArithmeticException.class)
    //@HystrixCommand(fallbackMethod = "tempHello")
    public String hello(){
        int i = 1/0;
        return restTemplate.getForObject("http://provider/hello",String.class);
    }

    /**
     * 通过注解实现请求 异步调用
     * @return Future
     */
    public Future<String> hello2(){
        return new AsyncResult<String>() {
            @Override
            public String invoke() {
                return restTemplate.getForObject("http://provider/hello",String.class);
            }
        };
    }

    /**
     * 注意：
     * 这个方法的名字要和fallbackMethod 一致
     * 方法返回值一致
     */

    public String tempHello(){
        return "tempHello";
    }

    /**
     * 如果需要获取 消费者中产生的异常 可以用下面这个方法代替上面的方法
     */

//    public String tempHello(Throwable t){
//        return "tempHello " + t.getMessage();
//    }

    @HystrixCommand(fallbackMethod = "error2")
    @CacheResult //这个注解表示该方法的请求结果会被缓存起来，默认情况下 缓存的key就是方法的参数，缓存的value 就是方法的返回值
    public String hello3(String name){
//        int i = 1/0;
        return restTemplate.getForObject("http://provider/hello2?name={1}",String.class,name);
    }

    public String error2(String name,Throwable t){
        return "error2 ..."+ name + ">>>>" + t.getMessage();
    }


}
